package com.funtask.fun.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.funtask.fun.entity.Issues;
import com.funtask.fun.entity.Project;
import com.funtask.fun.enums.IssueStatus;
import com.funtask.fun.manager.ProjectUserRelationManager;
import com.funtask.fun.mapper.IssuesMapper;
import com.funtask.fun.mapper.ProjectMapper;
import com.funtask.fun.service.IProjectService;
import com.funtask.fun.utils.BeanUtil;
import com.funtask.fun.utils.SecurityUtil;
import com.funtask.fun.vo.ProjectDetailVo;
import com.funtask.fun.vo.ProjectVo;
import com.funtask.fun.vo.UserVo;
import com.funtask.fun.vo.sub.IssueTypePair;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * @author zhangqi
 * @date 2024/1/5
 * @time 08:23
 * @description
 */
@Service
@Slf4j
public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project>
        implements IProjectService {
    @Autowired
    private ProjectUserRelationManager projectUserRelationManager;
    @Autowired
    private IssuesMapper issuesMapper;

    @Transactional
    @Override
    public Boolean createProj(Project project) {
        Long userId = SecurityUtil.getCurrentUser().getId();
        project.setJoinCount(1);
        project.setCreatorId(userId);
        boolean saveProj = super.save(project);
        if (saveProj) {
            Boolean saveRelation = projectUserRelationManager.saveRelation(userId, project.getId());
            if (!saveRelation){
                throw new RuntimeException("saveRelation false");
            }
            return saveRelation;
        }
        return false;
    }

    @Override
    public List<ProjectVo> selectProjVos() {
        return baseMapper.listProjectVos(SecurityUtil.getCurrentUser().getId());
    }

    @Override
    public ProjectDetailVo getDetailVoById(Long id) {
        Project project = baseMapper.selectById(id);
        ProjectDetailVo projectDetailVo = BeanUtil.getClass(ProjectDetailVo.class, project).get();
        List<UserVo> userVoList = projectUserRelationManager.getUserVoListByProjectId(id);
        projectDetailVo.setUserVoList(userVoList);
        List<Issues> issuesList = issuesMapper.selectByProjectId(id,null);
        log.info("issuesList:{}",issuesList);
        if (CollectionUtil.isNotEmpty(issuesList)){
            Map<Long, List<Issues>> issuesTypeMap = issuesList.stream()
                    .collect(Collectors.groupingBy(Issues::getIssuesTypeId));
//            Map<Long, String> issuesTypeIdValMap = issuesList.stream()
//                    .collect(Collectors.toMap(Issues::getIssuesTypeId,Issues::getIssuesTypeStr));
            Set<Long> issueTypeKeySet = issuesTypeMap.keySet();
            log.info("issuesTypeMap.size:{}",issuesTypeMap.size());
            Map<Long,Long[]> countsMap =null;
            for (int i=0;i<IssueStatus.values().length;i++){
                IssueStatus issueStatus = IssueStatus.values()[i];
                for (Long issueTypeId : issueTypeKeySet) {
                    if (countsMap==null){
                        countsMap = new HashMap<>();
                    }
                    List<Issues> issues = issuesTypeMap.get(issueTypeId);
                    long count = issues.stream().filter(is -> is.getStatus().equals(issueStatus.getCode())).count();
                    Long[] counts = null;
                    if (countsMap.get(issueTypeId)==null){
                        counts = new Long[IssueStatus.values().length];
                        Arrays.fill(counts,0L);
                    }else{
                        counts = countsMap.get(issueTypeId);
                    }
                    counts[i] = count;
                    countsMap.put(issueTypeId,counts);
                }

            }
            assert countsMap != null;
            Set<Long> typeIdSet = countsMap.keySet();
            List<IssueTypePair> issueTypePairs = new ArrayList<>();
            for (Long typeId : typeIdSet) {
                Long[] counts = countsMap.get(typeId);
                List<Long> countsList = Arrays.stream(counts).collect(Collectors.toList());
                Collections.reverse(countsList);
                long[] countsReverse = countsList.stream().mapToLong(Long::longValue).toArray();
                IssueTypePair issueTypePair = IssueTypePair.builder().typeId(typeId)
                        .typeName(issuesTypeMap.get(typeId).get(0).getIssuesTypeStr())
                        .counts(countsReverse).build();
                issueTypePairs.add(issueTypePair);
            }
            projectDetailVo.setIssueTypePairs(issueTypePairs);
        }
        log.info("projectDetailVo issueTypePairs:{}",projectDetailVo.getIssueTypePairs());
        return projectDetailVo;
    }
}
